package architect;

import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;

/**
 * Hello world!
 */
public class App {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");

        list.stream()
                .map(item -> item.toUpperCase())
                .filter(item -> list.indexOf(item.toLowerCase()) % 2 == 0)
                .forEach(System.out::println);

        Supplier<Person> supplierPerson = Person::new;
        Person p = supplierPerson.get();
        p.setName("shijia");
        p.setAge(18);
        p.setCapital(new BigDecimal(50000000));
        p.setMa(Boolean.TRUE);
        p.setSalary(30000d);

        if (true) {
            List<Wife> persons = new ArrayList<>();
            Wife w1 = new Wife();
            w1.setName("xiaofang");
            w1.setAge(18);
            persons.add(w1);
            Wife w2 = new Wife();
            w2.setName("xiaozhu");
            w2.setAge(16);
            persons.add(w2);
            p.setData(persons);
        } else {
            Wife w3 = new Wife();
            w3.setName("xiaoxiao");
            w3.setAge(17);
            p.setData(w3);
        }

        System.out.println(p.toString());

        GsonBuilder builder = new GsonBuilder();
        builder.setDateFormat("yyyy-MM-dd HH:mm:ss");
        builder.serializeSpecialFloatingPointValues();

        builder.addSerializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes fieldAttributes) {
                final Expose expose = fieldAttributes.getAnnotation(Expose.class);
                return expose != null && !expose.serialize();
                //return fieldAttributes.getName().contains("age");
            }

            @Override
            public boolean shouldSkipClass(Class<?> aClass) {
                return false;
            }
        }).addDeserializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes fieldAttributes) {
                final Expose expose = fieldAttributes.getAnnotation(Expose.class);
                return expose != null && !expose.deserialize();
            }

            @Override
            public boolean shouldSkipClass(Class<?> aClass) {
                return false;
            }
        });

        Gson gson = builder.create();
        String json = gson.toJson(p);
        System.out.println(json);

    }
}

class Person {

    private String name;
    private Integer age;
    private Double salary;
    private BigDecimal capital;
    private Boolean isMa;
    private Object data;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    public BigDecimal getCapital() {
        return capital;
    }

    public void setCapital(BigDecimal capital) {
        this.capital = capital;
    }

    public Boolean getMa() {
        return isMa;
    }

    public void setMa(Boolean ma) {
        isMa = ma;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
    }
}

class Wife {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
    }
}
